/**
 * 
 */
package wong.board.client.util;

import java.util.Date;

import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.i18n.shared.DateTimeFormat;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * @author wong
 * 
 */
public class DebugTool {

	private DebugTool() {
	}

	private static String indent = "";
	private static DateTimeFormat format = DateTimeFormat.getFormat("HH:mm:ss.SSS");// yyyyMMdd'-'HH:mm:ss.SSS

	private static HTML errorLabel;

	private static HTML getErrorLabel() {
		if (errorLabel == null) {
			errorLabel = new HTML();
			errorLabel.setStyleName("error-label");
			Style style = errorLabel.getElement().getStyle();
			style.setWidth(100, Unit.PCT);
			style.setColor("red");
			style.setBackgroundColor("yellow");
			style.setPosition(Position.FIXED);
			RootPanel.get().add(errorLabel);
			// RootPanel.get().insert(errorLabel, 0);
		}
		return errorLabel;
	}

	public static void showError(String msg, Throwable error) {
		StringBuffer buffer = new StringBuffer();
		if (msg != null) {
			// error(msg);
			buffer.append("<p style='color:red;'>" + msg + "</p>\n");
		}
		if (error != null) {
			buffer.append("<pre>" + error + "</pre>\n");
		}
		if (buffer.length() > 0) {
			HTML out = getErrorLabel();
			String html = out.getHTML() + buffer.toString();
			out.setHTML(html);
		}
	}

	/**
	 * dumps a stack trace to the console of the browser.
	 */
	public static void trace(String prefix) {
		StackTraceElement[] els = new RuntimeException("DUMMY").getStackTrace();
		for (int i = 3; i < els.length; i++) {
			String msg = (i + 1) + ".:" + (i < 3 ? "[" : " ") + els[i].toString() + (i < 3 ? "]" : " ");
			logToConsole(prefix + "[TRACE]:" + indent, "=", msg);
		}
	}

	public static void trace(String prefix, Throwable th, int offset) {
		StackTraceElement[] els = th.getStackTrace();
		for (int i = offset; i < els.length; i++) {
			String msg = (i + 1) + ".:" + (i < offset ? "[" : " ") + els[i].toString()
					+ (i < offset ? "]" : " ");
			errorToConsole(prefix + "[TRACE]:" + indent, "=", msg);
		}
	}

	/**
	 * Logs an 'enter'-message to the console of the browser and does an indent.
	 */
	public static void enter(String prefix, String msg) {
		logToConsole(prefix + "[ENTER]:" + indent, ">", msg);
		indent = indent + " ";
	}

	/**
	 * Logs an 'exit'-message to the console of the browser and does an outdent.
	 */
	public static void exit(String prefix, String msg) {
		int length = indent.length();
		indent = length > 0 ? (indent.substring(0, length - 1)) : "";
		logToConsole(prefix + " [EXIT]:" + indent, "<", msg);
	}

	private static String getTimestamp() {
		return format.format(new Date());
	}

	/**
	 * The actual writing to the console of the browser.
	 */
	private static native void logToConsole(String prefix, String delimiter, String msg) /*-{
		console.log(prefix + delimiter + msg);
	}-*/;

	/**
	 * The actual writing to the console of the browser.
	 */
	private static native void debugToConsole(String prefix, String delimiter, String msg) /*-{
		console.debug(prefix + delimiter + msg);
	}-*/;

	/**
	 * The actual writing to the console of the browser.
	 */
	private static native void infoToConsole(String prefix, String delimiter, String msg) /*-{
		console.info(prefix + delimiter + msg);
	}-*/;

	/**
	 * The actual writing to the console of the browser.
	 */
	private static native void warnToConsole(String prefix, String delimiter, String msg) /*-{
		console.warn(prefix + delimiter + msg);
	}-*/;

	/**
	 * The actual writing to the console of the browser.
	 */
	private static native void errorToConsole(String prefix, String delimiter, String msg) /*-{
		console.error(prefix + delimiter + msg);
	}-*/;

	/**
	 * The actual writing to the console of the browser.
	 */
	private static native void exceptionToConsole(Exception th) /*-{
		console.exception(th);
	}-*/;

}
